package com.meilian.tbcrm.java.tmc.util;

import org.apache.commons.lang3.StringUtils;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

/**
 * String工具类
 *
 * @author 陈杰
 * @time 2016年4月14日 14:48:53
 * @version v0.1
 *
 * Copyright ChenJie(chenjie_java@aliyun.com)
 */
public class StringKit extends StringUtils {

    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

    /**
     * 生成UUID
     * @return String
     * */
    public static String getUUId(){
        return UUID.randomUUID().toString();
    }


    /**
     * 按照gsm协议分割长短信内容
     *
     * @param smsContent 短信内容
     * @param wordCountP 通道字数
     * */
    public static String[] cutSmsContentByWordCount(String smsContent,int wordCountP){
        if(StringKit.isEmpty(smsContent)) return new String[]{""};
        else if(smsContent.length() <= wordCountP) {
            return new String[]{smsContent};
        }else{
            //长短信短信条数
            int wordCount = wordCountP - 3;
            int smsCount = smsContent.length() % wordCount == 0 ? smsContent.length() / wordCount  : smsContent.length() / wordCount + 1;
            String[] returnStringArray = new String[smsCount];
            for(int i = 1;i<=smsCount;i++){
                int start = (i - 1) * wordCount;
                int end = (i == smsCount) ? smsContent.length() : i * wordCount;
                String thisValue = smsContent.substring(start,end);
                returnStringArray[i-1] = thisValue;
            }
            return returnStringArray;
        }
    }

    /**
     * 转换Map类型为String
     *
     * @param  mapRecord 源map数据
     * @param  keySeq key和value的拼接方式
     * @param  itemsSeq 多个键值对的拼接方式
     * */
    public static String mapRecordToString(Map<String,Object> mapRecord, String keySeq, String itemsSeq){
        if(mapRecord==null || mapRecord.size() <=0) return "";
        StringBuilder returnString = new StringBuilder();
        for(String key : mapRecord.keySet()){
            returnString.append(key).append(keySeq).append(mapRecord.get(key)).append(itemsSeq);
        }
        return returnString.substring(0,returnString.length() - itemsSeq.length());
    }

    /**
     * 按照长度分割字符串
     * @param  str 源str数据
     * @param  length 分割的长度
     * */
    public static String[] splitByLength(String str,int length){
        if(str.length()>=length){
            int arrayList = str.length() % length == 0 ? str.length() / length : str.length() / length + 1;
            String[] returnArray = new String[arrayList];
            StringBuilder sb = new StringBuilder(str);
            for(int i = 0,j=0;i<=arrayList;j++){
                int end = i+length;
                returnArray[j] = sb.substring(i,i+length);
                i = end;
            }
            return returnArray;
        }
        return null;
    }

    /**
     * 从内容字符串中截取签名
     * 截取规则：1.如果签名前置，并且签名长度（包含两个括号）小于11，截取此签名
     *          2.如果签名未前置，截取最后一对括号的内容（包含括号）
     * @param content 短信内容
     * @return String[] 数组第一位为签名信息，包含括号；数组第二位为去除签名之后的短信内容
     * */
    public static String[] cutSignatureFromContent(String content){
        String[] returnArray = new String[]{"",content};
        int startIndex = content.indexOf("【"),endIndex = startIndex == 0 ? content.indexOf('】') : -1;
        if(startIndex==0 && endIndex>0 && endIndex<10 ){
            returnArray[0] = content.substring(startIndex,endIndex+1);
            returnArray[1] = content.substring(endIndex+1,content.length());
        }else {
            startIndex = content.lastIndexOf("【");
            endIndex = startIndex > 0 ? content.lastIndexOf('】') : -1;
            if (endIndex > 0 && endIndex > startIndex) {
                returnArray[0] = content.substring(startIndex, endIndex + 1);
                returnArray[1] = content.substring(0, startIndex) + (endIndex + 1 <= content.length() ? "" : content.substring(endIndex + 1, content.length()));
            }
        }
        return returnArray;
    }

    /**
     * 字符串补位
     * */
    public static String stringSupplement(String inputStr,int length){
        if(inputStr.length()<length){
            StringBuilder outStr = new StringBuilder();
            for(int i = 0;i<(length-inputStr.length());i++){
                outStr.append("0");
            }
            outStr.append(inputStr);
            return outStr.toString();
        }else{
            return inputStr;
        }
    }

    public static String byteToString(byte[] data, byte fmt) throws UnsupportedEncodingException {
        String content = "";
        switch (fmt) {
            case 0:
                content = new String(data);
                break;
            case 8:
                content = new String(data, "UTF-16BE");
                break;
            case 15:
                content = new String(data, "GBK");
                break;
            default:
                content = new String(data);
                break;
        }
        return content;
    }

    public static byte[] addStringByFmt(String string,int fmt){
        byte[] stringByte = null;
        try {
            switch (fmt) {
                case 0:
                    stringByte = string.getBytes();
                    break;
                case 8:
                    stringByte = string.getBytes("UTF-16BE");
                    break;
                case 15:
                    stringByte = string.getBytes("GBK");
                    break;
                default:
                    stringByte = string.getBytes();
                    break;
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return stringByte;
    }

    /**
     * 把异常的堆栈信息转换成String
     *
     * @param e 异常
     * */
    public static String parseExceptionToString(Throwable e){
        try {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            return "\r\n" + sw.toString();
        } catch (Exception e2) {
        }
        return "";
    }

    public static String noEmpty(String value){
        if(StringKit.isEmpty(value)){
            return "";
        }
        return value;
    }

    public static String toDecodeString(String str,String charSet){
        try {
            return java.net.URLDecoder.decode(str,charSet);
        } catch (UnsupportedEncodingException e) {
        }
        return str;
    }

    /**
     * 转化驼峰写法
     *  <desc> user_name   userName </desc>
     *
     * @param input
     * */
    public static String toHumpType(String input){
        StringBuilder sb = new StringBuilder();
        String[] underStr = input.split("_");
        for(int i = 0;i<underStr.length;i++){
            if(i==0) sb.append(underStr[i]);
            else sb.append(underStr[i].substring(0,1).toUpperCase()).append(underStr[i].substring(1));
        }
        return sb.toString();
    }

    public static String getFieldGetterName(String fieldName){
        if(StringKit.isNotEmpty(fieldName)){
            StringBuffer returnString = new StringBuffer("get");
            returnString.append(fieldName.substring(0,1).toUpperCase()).append(fieldName.substring(1));
            return returnString.toString();
        }
        return null;
    }

    public static String getFieldSetterName(String fieldName){
        if(StringKit.isNotEmpty(fieldName)){
            StringBuffer returnString = new StringBuffer("set");
            returnString.append(fieldName.substring(0,1).toUpperCase()).append(fieldName.substring(1));
            return returnString.toString();
        }
        return null;
    }

    /**
     * 通过现有的文件名称获取后缀
     *
     * @param filename
     * @param defaultValue
     *
     * @return String
     * */
    public static String getFileSuffix(String filename,String defaultValue) {
        int index = filename.indexOf(".");
        if(index>0){
            return filename.substring(index,filename.length() - index);
        }else{
            return defaultValue;
        }
    }

    /**
     * 随机获取UUID字符串(无中划线)
     *
     * @return UUID字符串
     */
    public static String getUUID() {
        String uuid = UUID.randomUUID().toString();
        return uuid.substring(0, 8) + uuid.substring(9, 13) + uuid.substring(14, 18) + uuid.substring(19, 23)
                + uuid.substring(24);
    }

    /**
     * 随机获取字符串
     *
     * @param length
     *            随机字符串长度
     *
     * @return 随机字符串
     */
    public static String getRandomString(int length) {
        if (length <= 0) {
            return "";
        }
        char[] randomChar = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p',
                'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'z', 'x', 'c', 'v', 'b', 'n', 'm' };
        Random random = new Random();
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0; i < length; i++) {
            stringBuffer.append(randomChar[Math.abs(random.nextInt()) % randomChar.length]);
        }
        return stringBuffer.toString();
    }

    /**
     * 根据指定长度 分隔字符串
     *
     * @param str
     *            需要处理的字符串
     * @param length
     *            分隔长度
     *
     * @return 字符串集合
     */
    public static List<String> splitString(String str, int length) {
        List<String> list = new ArrayList<String>();
        for (int i = 0; i < str.length(); i += length) {
            int endIndex = i + length;
            if (endIndex <= str.length()) {
                list.add(str.substring(i, i + length));
            } else {
                list.add(str.substring(i, str.length() - 1));
            }
        }
        return list;
    }

    /**
     * 将字符串List转化为字符串，以分隔符间隔.
     *
     * @param list
     *            需要处理的List.
     *
     * @param separator
     *            分隔符.
     *
     * @return 转化后的字符串
     */
    public static String toString(List<String> list, String separator) {
        StringBuffer stringBuffer = new StringBuffer();
        for (String str : list) {
            stringBuffer.append(separator + str);
        }
        stringBuffer.deleteCharAt(0);
        return stringBuffer.toString();
    }

    /**
     * 获取String类型，如果为空或者NULL返回空字符串
     *
     * @param objectIn 获取对象
     * */
    public static String getString(Object objectIn){
        return StringKit.getString(objectIn,"");
    }
    /**
     * 获取String类型，如果为空或者NULL返回空字符串
     *
     * @param objectIn 获取对象
     * @param emptyTemp 返回的指定字符串
     * */
    public static String getString(Object objectIn,String emptyTemp){
        if(objectIn!=null && StringKit.isNotEmpty(objectIn.toString())){
            return objectIn.toString();
        }else{
            return StringKit.isNotEmpty(emptyTemp) ?  emptyTemp : "";
        }
    }

    /**
     * 得到6位短信数字随机数
     * @return result
     */
    public static String getSmsRandom() {
        Random rad=new Random();
        String result = rad.nextInt(1000000) +"";
        if(result.length()!=6){
            return getSmsRandom();
        }
        return result;
    }

    /**
     * map转换String
     * */
    public static String parseMapToString(Map<?,?> mapIn){
        return StringKit.parseMapToString(mapIn,":"," ");
    }

    public static String parseMapToString(Map<?,?> mapIn,String valueSe,String itemSe){
        if(mapIn!=null && mapIn.size()>0){
            StringBuilder returnString = new StringBuilder();
            for(Object key : mapIn.keySet()){
                Object value = mapIn.get(key);
                returnString.append(key.toString()).append(valueSe).append(value!=null ? value.toString():"").append(itemSe);
            }
            return returnString.substring(0,returnString.length() - itemSe.length());
        }
        return "";
    }

    /**
     * 将Map对象通过反射机制转换成Bean对象
     *
     * @param map 存放数据的map对象
     * @param clazz 待转换的class
     * @return 转换后的Bean对象
     * @throws Exception 异常
     */
    public static Object mapToBean(Map<String, Object> map, Class<?> clazz) throws Exception {
        Object obj = clazz.newInstance();
        if(map != null && map.size() > 0) {
            for(Map.Entry<String, Object> entry : map.entrySet()) {
                String propertyName = entry.getKey();       //属性名
                Object value = entry.getValue();
                String setMethodName = "set"
                        + propertyName.substring(0, 1).toUpperCase()
                        + propertyName.substring(1);
                Field field = getClassField(clazz, propertyName);
                if(field==null)
                    continue;
                Class<?> fieldTypeClass = field.getType();
                value = convertValType(value, fieldTypeClass);
                try{
                    clazz.getMethod(setMethodName, field.getType()).invoke(obj, value);
                }catch(NoSuchMethodException e){
                    e.printStackTrace();
                }
            }
        }
        return obj;
    }

    /**
     * 获取指定字段名称查找在class中的对应的Field对象(包括查找父类)
     *
     * @param clazz 指定的class
     * @param fieldName 字段名称
     * @return Field对象
     */
    private static Field getClassField(Class<?> clazz, String fieldName) {
        if( Object.class.getName().equals(clazz.getName())) {
            return null;
        }
        Field []declaredFields = clazz.getDeclaredFields();
        for (Field field : declaredFields) {
            if (field.getName().equals(fieldName)) {
                return field;
            }
        }

        Class<?> superClass = clazz.getSuperclass();
        if(superClass != null) {// 简单的递归一下
            return getClassField(superClass, fieldName);
        }
        return null;
    }

    /**
     * 将Object类型的值，转换成bean对象属性里对应的类型值
     *
     * @param value Object对象值
     * @param fieldTypeClass 属性的类型
     * @return 转换后的值
     */
    private static Object convertValType(Object value, Class<?> fieldTypeClass) {
        Object retVal = null;
        if(Long.class.getName().equals(fieldTypeClass.getName())
                || long.class.getName().equals(fieldTypeClass.getName())) {
            retVal = Long.parseLong(value.toString());
        } else if(Integer.class.getName().equals(fieldTypeClass.getName())
                || int.class.getName().equals(fieldTypeClass.getName())) {
            retVal = Integer.parseInt(value.toString());
        } else if(Float.class.getName().equals(fieldTypeClass.getName())
                || float.class.getName().equals(fieldTypeClass.getName())) {
            retVal = Float.parseFloat(value.toString());
        } else if(Double.class.getName().equals(fieldTypeClass.getName())
                || double.class.getName().equals(fieldTypeClass.getName())) {
            retVal = Double.parseDouble(value.toString());
        } else if(LocalDateTime.class.getName().equals(fieldTypeClass.getName())){
            retVal = LocalDateTime.parse(value.toString());
        } else if(List.class.getName().equals(fieldTypeClass.getName())){
            String stringArray = value.toString().substring(1,value.toString().length()-1);
            String valueArray[] = stringArray.toString().split(",");
            List<String> demoList = Arrays.asList(valueArray);
            retVal = demoList;
        }else {
            retVal = value;
        }
        return retVal;
    }

}
